#include <exception>
#include <iostream>
#include <vector>

#include "wxx/os_info.hpp"

//#include "wxx/com/com_object.hpp"
#include "wxx/clr/fusion/assembly_name.hpp"
#include "wxx/com/com_ptr.hpp"
#include "wxx/com/com_thread.hpp"
#include "wxx/com/clsid.hpp"
#include "wxx/memory.hpp"
#include "wxx/memory/heap.hpp"
#include "wxx/guid.hpp"
#include "wxx/process_info.hpp"
#include "wxx/system_info.hpp"
#include "wxx/wxx_error.hpp"
#include "wxx/ptr_bitset_t.hpp"

using namespace std;

using namespace wxx;
using namespace wxx::com;

void __cdecl wmain(int, wchar_t*[])
{
	wcout << system_info() << endl;
	wcout << os_info() << endl;

	com_thread coinit(com_thread::mta);

	try
	{
		//wxx::clr::fusion::assembly_name name(L"System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
		
		//typedef vector<int, com_allocator<int>> com_int_vector;
		//com_int_vector vec;
		//vec.reserve(12);
		//
		//for(com_int_vector::iterator it = vec.begin(); it != vec.end(); ++it)
		//{
		//	*it = rand();
		//	wcout << *it << L", ";
		//}
		//wcout << endl;


		stringstream strs("11111111-1111-1111-1111-111111111111"
						  "{22222222-2222-2222-2222-222222222222}"
						  "33333333333333333333333333333333");

		guid g1, g2, g3;

		strs >> g1;
		strs >> g2;
		strs >> g3;

		guid g;
		::GUID empty = { 0 };

		assert(empty == guid::empty);
		assert(guid::empty == empty);

		guid empty_guid(empty);
		assert(empty == empty_guid);
		assert(empty_guid == empty);

		wcout << "is_wow64? " << process_info::current().is_wow64() << endl;
		
		wcout << guid::noshowbraces << guid::noshowhyphens;
		wcout << guid::empty << endl;

		wcout << guid::showhyphens;
		wcout << g << endl;

		wcout << guid::showbraces;
		wcout << g << endl;

		cout << static_cast<string>(g) << endl;

		GUID xx = { 1, 2, 4 };
		
		clsid cid(xx);
	
		wcout << cid << endl;

		clsid fso = clsid::from_progid(L"Scripting.FileSystemObject");
		//cout << fso.str() << endl;

		clsid fso2(OLESTR("0d43fe01-f093-11cf-894000a0c9054228"));
		bool equal = (fso == fso2);
		cout << "fso == fso2: " << equal << endl;

		IDispatch* ptr;
		ensure_success_hr(::CoCreateInstance(fso, 0, CLSCTX_INPROC_SERVER, IID_IDispatch, 
			reinterpret_cast<LPVOID*>(&ptr)));

		wcout << ptr << endl;
	}
	catch(const exception& exc)
	{
		cout << exc.what() << endl;
	}


}